<?php


//模板引擎文件

/**
*	步骤:
*		1、拼接html文件的去全路径,并判断该文件是否存在
*		2、判断缓存文件目录的权限 , 新建函数 checkDir用于判断文件夹权限
*		3、读取html格式文件内容
*		4、将html格式的文件编译为混编的 PHP 格式的文件 , 新建 compile编译函数
*		5、生成缓存文件名,并生成缓存文件全路径
*		6、将php格式的文件内容写入缓存文件全路径中
*		7、判断是否存在数组,并包含缓存文件全路径
*		注意: 模板文件 ==== html格式的文件
*/



//模板引擎函数
/**
*	@功能:	将html格式内容转化为php格式的内容,并包含使用php文件
*	@param1: 模板文件 (即 html文件)
*	@param2: 打包的数组 (必须用 compact打包,否则报错)
*	@返回值: 生成php格式的缓存文件,并使用该缓存文件
*
*/

function display($tplName , $data = null) {
	
	// var_dump($tplName);
	//拼接生成html文件全路径
	if (strstr($tplName , 'admin_')) {

		//后台模板
		$tplPath = rtrim(TPL_VIEW_ADMIN, '/') . '/' . $tplName;
		$tplCache = TPL_CACHE_ADMIN;
		
		//var_dump($tplPath);
	} else {

		//前台模板
		$tplPath = rtrim(TPL_VIEW_HOME, '/') . '/' . $tplName;
		$tplCache = TPL_CACHE_HOME;
		//var_dump($tplPath);
	}
	
	// var_dump($tplPath);
	//判断模板文件(即html文件)是否存在
	if (!file_exists($tplPath)) {
		
		exit('模板文件不存在');
	}
	

	//判断缓存文件目录是否有权限(可读,可执行)
	if (!checkDir($tplCache)) {
		
		exit('没有权限写内容');
	}
	
	//修改缓存文件名
	$cacheFile =  str_replace('.' , '_' , $tplName) . '.php';
	//var_dump($cacheFile);
	
	//生成缓存文件全路径
	$cacheFilePath = rtrim($tplCache, '/') . '/' . $cacheFile; 
	
	//读取html格式文件
	$htmlContent = file_get_contents($tplPath);
	//var_dump($htmlContent);
	
	//编译html格式的文件,生成php格式的文件内容 (即 把html格式 转换为 php格式)
	$phpContent = compile($htmlContent);
	
	//将编译好的php格式的文件写入缓存全路径中
	file_put_contents($cacheFilePath , $phpContent);
	
	//判断参数 2 (即$data) 是否为数组
	if (is_array($data)) {
		
		//解开数组,释放出变量
		extract($data);
		
		include $cacheFilePath;
	}
	
}

//封装一个 判断文件夹权限的函数
/**
*	@功能:	判断文件目录的权限
*	@param1: 文件目录 (即不包含文件)
*	@返回值: 返回创建好的文件目录,修改权限后的文件,或布尔值true
*
*/

function checkDir($dirPath) {
	
	//判断文件夹或文件是否存在,存在时又是否为文件夹
	if (!file_exists($dirPath) || !is_dir($dirPath)) {
		
		//递归创建,权限为可读可执行的文件目录
		return mkdir($dirPath, 0755 , true);
	}
	
	//判断文件是否可读,可写
	if (!is_readable($dirPath) || !is_writeable($dirPath)) {
		
		var_dump($dirPath);
		//修改文件权限为可读可执行
		return chmod($dirPath , 0755);
	}
	
	return true;
}

//封装一个编译html的函数 (将html格式转换为php格式的文件)
//参数: html格式的文件内容(string型)
/**
*	@功能:	将html格式内容转化为php格式的内容,并包含使用php文件
*	@param1: html格式的文件内容 (string类型)
*	@返回值: 生成php格式的文件内容	(string类型)
*
*/

function compile($content) {
	
	//var_dump($content);
	
	//需要替换的数组   数组构造: 键为html占位格式, 值为php语法格式 , 其中的\1是变量名
	$array = [
		
		'{$%%}' 			=> 		'<?=$\1;?>',
		'{if %%}' 			=> 		'<?php if(\1):?>',
		'{/if}'				=> 		'<?php endif;?>',
		'{else}'			=> 		'<?php else: ?>',
		'{elseif %%}'   		=> 		'<?php elseif(\1):?>',
		'{else if %%}'  		=> 		'<?php elseif(\1):?>',
		'{foreach %%}'		=> 		'<?php foreach(\1):?>',
		'{/foreach}'			=> 		'<?php endforeach;?>',
		'{while %%}'			=>		'<?php while(\1):?>',
		'{/while}'			=> 		'<?php endwhile;?>',
		'{for %%}'			=> 		'<?php for(\1):?>',
		'{/for}'				=> 		'<?php endfor;?>',
		'{continue}'			=> 		'<?php continue;?>',
		'{switch %%}'  		=> 		'<?php switch (\1): ?>',
		'{case %%}'   		=> 		'<?php case \1: ?>',
		'{break}'      			=> 		'<?php break; ?>',
		'{/switch}'   			=> 		'<?php endswitch; ?>',
		'{$%%++}'			=> 		'<?php $\1++;?>',
		'{$%%--}'			=> 		'<?php $\1--;?>',
		'{/*}'				=> 		'<?php /*',
		'{*/}'				=> 		'*/?>',
		'{section}'			=> 		'<?php ',
		'{/section}'			=> 		'?>',
		'{$%% = $%%}'		=> 		'<?php $\1 = $\2;?>',
		'{default}'			=> 		'<?php default:?>',
		'{include %%}'		=> 		'<?php include "\1";?>',
		
		//自添加
		'{var_dump %%}'		=> 		'<?php var_dump(\1);?>'

	];
	
	//将数组中的键值全部转换成正则格式
	foreach ($array as $key => $value) {
		
		//定义正则: 先用preg_qiote() 给正则字符和边界符号# 前面加上转义符号 \ ;再用取消贪婪的 (.*?) 防止同一行的两个变量被解析成一个变量;接着用取消贪婪替换掉占位符 %% ;接着拼接上边界符 # 
		$pattern = '#' . str_replace('%%', '(.*?)' , preg_quote($key , '#')) . '#';
	
		//判断键中是否存在 include 关键字
		if (strstr($key , 'include')) {
			
			//回调替换函数, 参数2为回调的函数名
			//将 含有 include 关键字的 html格式的内容回调处理
			$content = preg_replace_callback($pattern , 'parseInclude' ,$content);
		} else {
			
			//此处有坑: 当参数3 为是数组时, 函数 preg_replace() 接收返回值的变量必须和参数3为同名
			//根据正则将html格式内容替换成 php 格式内容
			$content = preg_replace($pattern , $value , $content);
		}
		
	}
	
	//var_dump($content);
	
	//返回php格式字符串
	return $content;
	
}


//封装一个处理包含include 关键字的 html格式内容
/**
*	@功能: 将包含 include 关键字的	html格式内容转化为php格式的内容,并包含使用php文件
*	@param1: html格式的文件内容 (string类型)
*	@返回值: 生成php格式的缓存文件,并使用该缓存文件
*
*/

function parseInclude($data) {
	
	//去除 文件名两边的引号, $data[1] , 表示 \1 ,即第一个()中的内容,此处指对应的html文件名,如test.html 
	$file = str_replace(['\'' , '"'] , '' , $data[1]);
	//作用同上,防呆处理,去除文件两边的 单,双引号
	//$file = trim($data[1] , '\'"');

	//递归调用模板函数
	display($file);
	
	//拼接缓存文件的全路径
	//$cacheFilePath = rtrim(TPL_CACHE , '/') . '/' . str_replace('.', '_' , $file) . '.php';
	
	
	//判断文件名中是否含有admin_ ,并拼接生成html文件全路径
	if (strstr($file , 'admin_')) {

		//后台缓存
		$cacheFilePath = rtrim(TPL_CACHE_ADMIN , '/') . '/' . str_replace('.', '_' , $file) . '.php';
	} else {

		//前台模板缓存
		$cacheFilePath = rtrim(TPL_CACHE_HOME , '/') . '/' . str_replace('.', '_' , $file) . '.php';
	}

	//包含缓存文件全路径
	return "<?php include '$cacheFilePath';?>";
	
}


